package com.ruoyi.web.controller.wechat;

import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.SHA1Util;
import com.ruoyi.wechat.config.Constant;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

/**
 * 微信网页授权相关
 *
 * @author yan
 */
@RestController
@RequestMapping("/wechat/user")
@Api(tags = {"微信网页授权-用户账号"})
@RequiredArgsConstructor
public class WxAuthController {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    private final WxMpService wxMpService;

    @RequestMapping("/getOpenId/{appId}")
    public AjaxResult publicOpenId(HttpServletResponse response, HttpServletRequest request, @PathVariable String appId) {
        if (com.ruoyi.common.utils.StringUtils.isEmpty(request.getParameter(Constant.CODE))) {
            try {
                response.sendRedirect("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=重定向网址" + appId + "&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect");
            } catch (IOException e) {
                e.printStackTrace();
                logger.error("获取微信公众号用户信息异常:", e);
            }
        } else {
            try {
                this.wxMpService.switchoverTo(appId);
                WxOAuth2AccessToken token = wxMpService.getOAuth2Service().getAccessToken(request.getParameter("code"));
                WxOAuth2UserInfo userInfo = wxMpService.getOAuth2Service().getUserInfo(token, "zh_CN");
                logger.info("获取微信用户信息:{}", userInfo);
                return AjaxResult.success("获取微信用户信息", userInfo);
            } catch (WxErrorException e) {
                logger.error("code换取用户信息失败", e);
                return AjaxResult.error(e.getError().getErrorMsg());
            }

        }
        return null;
    }


    /**
     * 获取微信分享的签名配置
     * 允许跨域（只有微信公众号添加了js安全域名的网站才能加载微信分享，故这里不对域名进行校验）
     *
     * @param request
     * @param response
     * @return
     */
    @GetMapping("/getShareSignature")
    @ApiOperation(value = "获取微信分享的签名配置", notes = "微信公众号添加了js安全域名的网站才能加载微信分享")
    public AjaxResult getShareSignature(HttpServletRequest request, HttpServletResponse response, @CookieValue String appid) throws WxErrorException {
        this.wxMpService.switchoverTo(appid);
        // 1.拼接url（当前网页的URL，不包含#及其后面部分）
        String wxShareUrl = request.getHeader("wx-client-href");
        if (!StringUtils.hasText(wxShareUrl)) {
            return AjaxResult.error("header中缺少wx-client-href参数，微信分享加载失败");
        }
        wxShareUrl = wxShareUrl.split("#")[0];
        Map<String, String> wxMap = new TreeMap<>();
        String wxNoncestr = UUID.randomUUID().toString();
        String wxTimestamp = (System.currentTimeMillis() / 1000) + "";
        wxMap.put("noncestr", wxNoncestr);
        wxMap.put("timestamp", wxTimestamp);
        wxMap.put("jsapi_ticket", wxMpService.getJsapiTicket());
        wxMap.put("url", wxShareUrl);

        // 加密获取signature
        StringBuilder wxBaseString = new StringBuilder();
        wxMap.forEach((key, value) -> wxBaseString.append(key).append("=").append(value).append("&"));
        String wxSignString = wxBaseString.substring(0, wxBaseString.length() - 1);
        // signature
        String wxSignature = SHA1Util.sha1(wxSignString);
        Map<String, String> resMap = new TreeMap<>();
        resMap.put("appId", appid);
        resMap.put("wxTimestamp", wxTimestamp);
        resMap.put("wxNoncestr", wxNoncestr);
        resMap.put("wxSignature", wxSignature);
        return AjaxResult.success(resMap);
    }
}
